#include "Option.h"
#include "Random.h"
#include <algorithm>
#include <math.h>
#include <sstream>
#include <fstream>
#include <ctype.h>
#include <cstdlib>
#include <unistd.h>
#include <string>
#include <vector>

using namespace std;

Option::Option()
{
    S0 = 10;
    r = 0.005;
    k = 11.0;
    sigma = 0.1;
    T = 30;
    N = 10000;
    randSample = new Random();
}

Option::Option(double s0, double rate, double strike, double sig, int t)
{
    S0 = s0;
    r = rate;
    k = strike;
    sigma = sig;
    T = t;
    randSample = new Random();
}

Option::Option(string filename)
{
    ifstream file (filename.c_str());
    string value;
    vector<string> store;  

    while (file.good()) {
        getline(file, value, ',');
        store.push_back(value);
    }

    S0 = atof(store[0].c_str());
    r = atof(store[1].c_str());
    k = atof(store[2].c_str());
    sigma = atof(store[3].c_str());
    T = atoi(store[4].c_str());
    N = 10000;

    randSample = new Random();
}
          
Option::~Option()
{
  delete randSample;
}

void Option::setPrice(double stock0) 
{
    S0 = stock0;
}

void Option::setInt(double rate)
{
    r = rate;
}

void Option::setStrike(double strike)
{
    if (strike) k = strike;
}

void Option::setVol(double volatility)
{
    sigma = volatility;
}

void Option::setDays(int days)
{
    T = days;
}

void Option::setTrialNumber(int n)
{
    if (n)
        N = n;
}

double Option::currentPrice(double rd)
{
    return S0*exp((r-pow(sigma,2)/2)*T+sigma*sqrt(T)*rd);
}

double Option::getPrice()
{
    double stock;
    double payoff;
    double rd, out;
    for (int i = 0; i < N; i++) { 
        rd = randSample->getNormRand();
        stock = currentPrice(rd);
        payoff = getPayOff(stock);
        out += payoff;
    }
    return exp(-r * T) * out / N;
}

<<<<<<< local
double CallOption::getPayOff(double stock)
=======
        
float PutOption::getPutPrice()
>>>>>>> other
{
<<<<<<< local
  return max(stock - k, 0.0);
=======
    float stock;
	float payoff;
	float out;
	Random::Random *randSample = new UnifRand();
	
	for (int i = 0; i < N; i++) {
	    float rd = randSample->rand();
		stock = currentPrice(rd);
		payoff = max(double(k-stock),0.0);
		out += payoff/double(N);
	}
	return out;
>>>>>>> other
}

double PutOption::getPayOff(double stock)
{
  return max(k - stock, 0.0);
}

ostream& operator<<(ostream& os, Option& cls)
{
    os << "# of simulation:    " << cls.N << "\nstock price:    " << cls.S0 << "\nstrike price:    " << cls.k << "\ndays:    " << cls.T << "\nvolatility:    " << cls.sigma <<  "\noption price: " << cls.getPrice() << "\n" <<  endl;
    return os;
}
